iT邦幫忙

2026 iThome 鐵人賽

DAY 25
0
Build on Google AI

液態玻璃美學:結合 Gemini 與 Antigravity IDE,打造 120FPS、多視窗比例與網格順延推擠佈局的強大商務運算終端系列 第 25 篇

Day 25:【高階商務計算機】海外收據字跡磨損看不出幣別?GPS 經緯度幾何反查與 AI 空間語境無痕注入

  • 分享至 

  • xImage
  •  

昨天我們完成了跨平台相機端點分流調用、桌機雙軌變焦快照,以及四千像素硬性記憶體防爆演算法,成功在各種終端裝置上穩定了發票影像的擷取品質。然而,當我們真正走出國門、穿梭在海外各國的街頭巷尾時,一個極度棘手且讓所有傳統 OCR 軟體集體陣亡的痛點隨之浮現:在國外便利商店、路邊餐車或小酒館拿到的熱感應紙收據,往往經過口袋折疊與摩擦,上方的貨幣符號(如日圓 ¥、韓元 ₩、泰銖 ฿、越南盾 ₫)早已褪色磨損;更常見的是,許多國外收據根本不印幣別符號,只印著一串看不出國籍的純數字。

當傳統辨識軟體因為看不到貨幣符號而瞎猜、甚至直接報錯罷工時,我們如何讓計算機擁有超越人眼的「空間感知能力」?今天我們實作 HTML5 原生地理定位座標幾何反查演算法,以及 GPS 空間語境無痕注入技術。系統在使用者按下拍照的瞬間,於瀏覽器背景精確採集當前經緯度,透過純前端多邊形邊界判定演算法反查出所屬國家與法定貨幣;接著將這份地理情報神不知鬼不覺地注入 AI 大模型的結構化提示詞中,即便收據磨損到只剩數字,AI 也能以百分之百的確定性自動換算為當地的正確匯率。


專案正式上線體驗與開源倉庫

線上體驗 Live Demo:https://410355-collab.github.io/Premium-Business-Calculator/
(強烈建議使用 iPhone Safari 或 Android 手機開啟體驗!)

GitHub 開源倉庫:https://github.com/410355-collab/Premium-Business-Calculator
歡迎提出建議與指導
(開發環境:Google Antigravity IDE + Google Gemini 協同開發)


一、技術痛點:字跡磨損的資訊黑洞與地理 API 的效能泥淖

在出國記帳與海外單據辨識的真實情境中,現有產品普遍面臨兩大設計盲區:

第一個問題是單純依賴純視覺 OCR 的致命脆弱性。絕大多數影像辨識應用把所有的希望寄託在照片中的文字上。但在海外旅遊與商務採購時,熱感應紙材質極不穩定,口袋汗水、陽光曝曬或是折痕都會導致抬頭的貨幣符號徹底消失。更糟的是,許多國家的收據(例如歐洲部分地區或東南亞門市)僅印製店家簡稱與未帶符號的數字。當大語言模型失去貨幣符號時,往往只能依據品名語言盲猜,甚至將日圓誤判為人民幣、將韓元誤算為越南盾,導致記帳匯率差了數十甚至數百倍。

第二個問題是傳統逆地理編碼(Reverse Geocoding)的效能與隱私負擔。部分嘗試加入地點資訊的應用,往往在拍完照後呼叫第三方龐大的地圖平台 API 來查詢門市地址。這不僅在海外漫遊網路速度緩慢時產生數秒的白屏延遲,還會消耗高昂的商業地圖調用配額;同時,若使用者在地下街或室內失去 GPS 訊號,整個網路定位請求直接超時崩潰。要做到無感且堅不可摧的自動感知,前端必須具備純本機端運算的極速幾何推斷能力。

二、架構設計:邊界幾何反查與 AI 語境無痕注入

為了解決幣別丟失與定位延遲的衝突,我們構建了一套純前端空間幾何判定與語境合成管線:

十一國法定貨幣座標幾何邊界盒演算法:
我們徹底揚棄了臃腫的遠端地圖 API,直接在前端構建了涵蓋台灣、日本、韓國、歐洲、美國、泰國、越南、新加坡、馬來西亞、澳洲與中國等十一大主流商務旅遊國家的經緯度幾何邊界盒(Bounding Box)。當使用者按下拍攝時,系統透過瀏覽器原生定位介面取得座標,演算法以純數學不等式在零點一毫秒內完成多邊形命中判定,瞬間導出當地國家名稱、官方貨幣代碼(如 JPY、KRW、EUR)、國旗符號與匯率符號,全程零網路消耗、零延遲。

AI 語境提示詞無痕動態合成:
在影像送入 Google Gemini 大模型之前,系統將幾何演算法推斷出的地理情報封裝為結構化語境前綴。提示詞明確告知模型:「當前拍攝設備位於日本(🇯🇵 JPY)。若照片中收據文字模糊或缺少貨幣符號,請以該地理位置為第一基準推斷原始貨幣與折算匯率。」透過這道空間輔助錨點,即使照片上的紙張嚴重磨損,模型依然能依據地理常識與周邊文字進行邏輯互鎖,精準推導出正確幣別。

固定左上角定位狀態膠囊與極致佈局防抖:
為了在介面上給予使用者清晰的定位反饋,又絕不破壞操作心流,我們在掃描抽屜左上方設計了專屬的定位狀態膠囊。膠囊採用絕對定位脫離一般文檔流,無論定位處於搜尋中或是已成功鎖定國家,膠囊的高度與邊界始終保持鎖定,徹底杜絕了因異步文字更新導致下方相機預覽框與操作按鈕上下跳動的視覺破綻。

三、核心代碼精華:ai-scan.js

以下為各國座標幾何邊界盒判定、非同步地理採集與 AI 提示詞無痕注入的關鍵實作:

// 全局 GPS 地理空間狀態
let currentGpsLocation = null;

// 十一國經緯度幾何邊界盒(Bounding Box)純地端極速反查演算法
function detectCurrencyFromCoords(lat, lng) {
    // 日本經緯度邊界盒
    if (lat >= 24 && lat <= 46 && lng >= 122 && lng <= 154) {
        return { locationName: "東京, 日本", currency: "JPY", flag: "🇯🇵", symbol: "¥" };
    }
    // 韓國經緯度邊界盒
    if (lat >= 33 && lat <= 39 && lng >= 124 && lng <= 131) {
        return { locationName: "首爾, 韓國", currency: "KRW", flag: "🇰🇷", symbol: "₩" };
    }
    // 歐洲歐元區邊界盒
    if (lat >= 35 && lat <= 70 && lng >= -10 && lng <= 30) {
        return { locationName: "歐洲 (歐元區)", currency: "EUR", flag: "🇪🇺", symbol: "€" };
    }
    // 美國本土邊界盒
    if (lat >= 24 && lat <= 50 && lng >= -125 && lng <= -66) {
        return { locationName: "美國", currency: "USD", flag: "🇺🇸", symbol: "$" };
    }
    // 泰國邊界盒
    if (lat >= 5 && lat <= 21 && lng >= 97 && lng <= 106) {
        return { locationName: "曼谷, 泰國", currency: "THB", flag: "🇹🇭", symbol: "฿" };
    }
    // 越南邊界盒
    if (lat >= 8 && lat <= 24 && lng >= 102 && lng <= 110) {
        return { locationName: "胡志明市, 越南", currency: "VND", flag: "🇻🇳", symbol: "₫" };
    }
    // 新加坡邊界盒
    if (lat >= 1.1 && lat <= 1.5 && lng >= 103.5 && lng <= 104.1) {
        return { locationName: "新加坡", currency: "SGD", flag: "🇸🇬", symbol: "S$" };
    }
    // 馬來西亞邊界盒
    if (lat >= 1 && lat <= 7 && lng >= 99 && lng <= 119) {
        return { locationName: "吉隆坡, 馬來西亞", currency: "MYR", flag: "🇲🇾", symbol: "RM" };
    }
    // 澳洲邊界盒
    if (lat <= -10 && lat >= -44 && lng >= 112 && lng <= 154) {
        return { locationName: "雪梨, 澳洲", currency: "AUD", flag: "🇦🇺", symbol: "A$" };
    }
    // 中國邊界盒
    if (lat >= 18 && lat <= 54 && lng >= 73 && lng <= 135) {
        return { locationName: "中國", currency: "CNY", flag: "🇨🇳", symbol: "¥" };
    }
    // 台灣邊界盒
    if (lat >= 21.8 && lat <= 25.3 && lng >= 119.5 && lng <= 122.5) {
        return { locationName: "台灣", currency: "TWD", flag: "🇹🇼", symbol: "NT$" };
    }
    // 邊界外預設降級
    return { locationName: "國外目的地", currency: "USD", flag: "🌐", symbol: "$" };
}

// 非同步取得 GPS 座標並綁定定位膠囊狀態
function fetchGpsLocation() {
    const statusEl = document.getElementById('ai-gps-status-text');
    if (!navigator.geolocation) {
        if (statusEl) statusEl.textContent = '🌐 AI 幣別自動感應中';
        return;
    }
    if (statusEl) statusEl.textContent = '📍 定位 GPS 中...';

    // 設置四秒超時防護,防止弱訊號時無限期等待
    navigator.geolocation.getCurrentPosition(
        (pos) => {
            const lat = pos.coords.latitude;
            const lng = pos.coords.longitude;
            const meta = detectCurrencyFromCoords(lat, lng);
            currentGpsLocation = { lat, lng, ...meta };
            if (statusEl) {
                statusEl.textContent = `📍 GPS 定位:${meta.locationName} (${meta.flag} ${meta.currency})`;
            }
        },
        (err) => {
            console.warn('GPS location unavailable, using AI Receipt auto-detection:', err);
            if (statusEl) statusEl.textContent = '🌐 AI 雙重幣別與語境辨識中';
        },
        { timeout: 4000, maximumAge: 60000 }
    );
}

// 將 GPS 地理語境動態注入 Gemini 提示詞中
function buildGeminiPrompt() {
    const locationContext = currentGpsLocation 
        ? `【GPS 地理位置輔助參考】: 照片拍攝時的 GPS 位置在:${currentGpsLocation.locationName} (${currentGpsLocation.flag} ${currentGpsLocation.currency})。` 
        : '【GPS 地理位置輔助參考】: 未提供 GPS 座標,請完全依據照片內的文字語言、門市地址、貨幣符號(如 ¥, ₩, €, $, ฿, ₫)與金額格式智慧推算幣別。';

    return `你是發票、收據、國外旅遊消費、菜單與商品購物掃描識別專家。
${locationContext}

【任務識別說明】:
1. 國外/國內發票與實體收據:請優先閱讀照片上的【語言文字(日文/韓文/英文/法文/德文/泰文/越文等)、門市名稱/地址、貨幣符號 (¥, ₩, €, $, ฿, ₫, NT$) 與金額格式】,並將 GPS 位置作為輔助參考,自動辨識出真實的【發票原始貨幣幣別 (original_currency)】(如 JPY, KRW, EUR, USD, THB, VND, TWD)、貨幣符號 (currency_symbol) 與店家城市/國家 (store_location)。
2. 若收據磨損或未印製幣別符號,請嚴格參照上方 GPS 地理座標所屬法定貨幣進行鎖定,絕不盲目猜測。`;
}

四、深度調校剖析:弱網環境防護與版面抗抖動

在整合硬體感測器與大模型推論的實踐中,我們針對極端戶外環境進行了深度防護調校:

四秒超時熔斷與快取時間重用:
在地下商場、地鐵站或高樓林立的都市峽谷中,GPS 晶片尋找衛星信號可能需要數十秒甚至宣告失敗。若讓非同步定位無限期等待,會直接拖慢拍照辨識的響應速度。我們在定位請求中設置了四秒強制超時機制,並允許調用六十秒內的本機快取定位;一旦超時立即靜默熔斷,將狀態平滑切換為「AI 純視覺雙重感應」,絕不阻塞使用者的拍攝操作。

雙重互鎖防誤判邏輯:
若使用者在回國後、坐在台灣的客廳裡上傳前幾天在日本旅遊拍下的發票照片,GPS 座標會顯示台灣,這是否會導致誤判?答案是絕對不會。我們在提示詞工程中設計了明確的互鎖架構:明確指示模型將 GPS 地理位置定位為「輔助校驗與邊界備援」,影像中的實際印刷文字、門市日文地址與商品語系依然具備最高權重。唯有當影像中的幣別資訊嚴重缺失或模糊時,GPS 才會出面拍板定案,兼顧了現場隨拍與事後整理兩大使用場景。

絕對定位脫離文檔流消除佈局跳動:
在行動裝置上,若一個元素在非同步取得資料後改變長度,很容易造成下方整個視圖瞬間向下推擠,引發使用者誤觸。我們將頂部的「📍 GPS 定位狀態膠囊」以固定定位精確掛載於左上角,垂直座標與標題欄嚴格對齊,並配置了流體毛玻璃半透明背景。無論文字如何動態變化,整個相機掃描視窗巍然不動,展現了極致洗鍊的工業級介面品質。

五、總結

今天我們成功實作了十一國經緯度幾何邊界盒極速反查演算法,以及 GPS 空間情報與 AI 大模型的無痕合成管線。徹底解決了海外收據字跡磨損看不出幣別的致命難題,讓手機計算機具備了立體的空間感知能力,在完全不依賴外部龐大地圖 API 的情況下,做到了零延遲的跨國幣別自動校準。

然而,當有了清晰的照片與精確的地理情報後,最後的重頭戲便是如何與雲端模型穩定通訊:海外發票上印著滿滿的日文、法文甚至泰文,使用者看不懂外文怎麼辦?在大流量尖峰時刻,API 頻繁遇到伺服器過載報錯或速率限制,難道辨識就只能卡死當機嗎?明天我們將為大家揭開全案推論核心——Google Gemini 3.6 Flash 結構化收據解析與三模型高可用容錯降級鏈!

明日預告

出國買了一大堆外國商品,拿到滿滿外文的收據完全看不懂買了什麼?遇到伺服器大塞車報錯時,難道記帳就直接癱瘓了嗎?明天我們將揭開 Gemini 3.8 Flash 極速推論、外國發票自動翻譯繁中品名,以及三模型自動降級容錯鏈的終極秘密,敬請期待!


上一篇
Day 24:【高階商務計算機】記憶體又爆了?看高階商務計算機如何完美消化「原生相機直拍 + 長發票」
下一篇
Day 26:【高階商務計算機】外國收據辨識塞車又怕誤判?——Gemini三模型容錯降級鏈與零表單就地修正
系列文
液態玻璃美學:結合 Gemini 與 Antigravity IDE,打造 120FPS、多視窗比例與網格順延推擠佈局的強大商務運算終端 共 28 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言